package sa.huang;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import javax.xml.namespace.QName;

import org.oasis_open.docs.wsbpel._2_0.plnktype.*;
import org.xmlsoap.schemas.wsdl.TDefinitions;

/**TODO
 * @author huang
 *
 */
public class WSDLHandler {

	private JAXBContext jaxbContext;
	private TDefinitions wsdlFile = null;
	
	public WSDLHandler() {
		try {
			jaxbContext = JAXBContext.newInstance("org.xmlsoap.schemas.wsdl");
		} catch (JAXBException e) {
			e.getStackTrace();
		}
	}
	/**
	 * based on algorithm 3.19
	 * the original xsd file of WSDL dosen't contain the definition of partnerLinkTypes
	 * since the algorithm only describes how to generate a wsdl file only contains the declaration of <partnerLinkTypes>
	 * so i changed the xsd file of WSDL, so that the partnerLinkTypes (defined in ws-bpel_plnktype.xsd, which is imported in wsdl.xsd)
	 * could be declared in wsdl using JAXB
	 * 
	 * drawback: namespace of the declared partnerLinkTypes is wsdl, not plnk
	 * @param data
	 */
	public void declarePartnerLinkTypes(Data data){
		TDefinitions tdef = new TDefinitions();
		tdef.setTargetNamespace(data.getTNS());
		for(String plt: data.getPartnerLinkTypeSet()){
			Comm comm = data.comm_plt(plt);
			TPartnerLinkType tplt = new TPartnerLinkType();
			tplt.setName(plt);
			TRole role = new TRole();
			role.setName(comm.getB());
			role.setPortType(comm.getB_pt());
			tplt.getRole().add(role);
			if(comm.getA_pt() != null){
				TRole role_1 = new TRole();
				role_1.setName(comm.getA().get(0));
				role_1.setPortType(comm.getA_pt());
				tplt.getRole().add(role_1);
			}
			tdef.getAnyTopLevelOptionalElement().add(tplt);
		}
		writeDefinition(tdef, "src/test/resources/generated-BPEL/test_LT.wsdl");
	}

	
	public TDefinitions loadDefinition(String filePath) {
		try {
			Unmarshaller u = jaxbContext.createUnmarshaller();
			wsdlFile = (TDefinitions)((JAXBElement<?>) u.unmarshal( new FileInputStream(filePath))).getValue();			
		} catch (IOException e) {
			e.printStackTrace();
		} catch (JAXBException e) {
			e.printStackTrace();
		}
		
		return wsdlFile;
	}
	
	public void writeDefinition(TDefinitions newWSDL, String filePath){
		
		try{
			Marshaller m = jaxbContext.createMarshaller();
			File newFile = new File(filePath);
			m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);			
			m.marshal(new JAXBElement<TDefinitions>(new QName("http://schemas.xmlsoap.org/wsdl/","definitions"), TDefinitions.class, newWSDL), newFile);
		} catch (JAXBException e) {
			e.printStackTrace();
		}

	}

}

